package cc.yaomm.service.basic.service.user;

import cc.yaomm.common.basic.enums.StatusEnum;
import cc.yaomm.common.basic.util.BeanUtils;
import cc.yaomm.common.biz.enums.OwnerTypeEnum;
import cc.yaomm.service.basic.entity.user.Permissions;
import cc.yaomm.service.basic.entity.user.Resources;
import cc.yaomm.service.basic.entity.user.UsersPermissionsRef;
import cc.yaomm.service.basic.manager.PermissionManager;
import cc.yaomm.service.basic.mapper.user.PermissionsMapper;
import cc.yaomm.service.basic.mapper.user.ResourcesMapper;
import cc.yaomm.service.basic.mapper.user.UsersPermissionsRefMapper;
import cc.yaomm.service.basic.service.user.bo.PermissionParamBO;
import cc.yaomm.service.basic.service.user.bo.PermissionResultBO;
import cc.yaomm.service.basic.service.user.bo.ResourceResultBO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created by XQL on 2021/6/9.
 */
@Service
@Validated
public class PermissionService {

    @Autowired
    private PermissionsMapper permissionsMapper;

    @Autowired
    private PermissionManager permissionManager;

    @Autowired
    private UsersPermissionsRefMapper usersPermissionsRefMapper;

    @Autowired
    private ResourcesMapper resourcesMapper;

    public List<PermissionResultBO> findTree(OwnerTypeEnum ownerType, StatusEnum status) {
        List<Permissions> list = permissionsMapper.findByOwnerType(ownerType, status);
        return permissionManager.convertTree(list);
    }

    /**
     * 锁定
     *
     * @param id
     */
    @Transactional
    public void lock(Long id, StatusEnum status) {
        Assert.notNull(id, "参数ID，不能为空");
        Assert.notNull(status, "参数status，不能为空");
        Permissions permissions = permissionsMapper.get(id);
        Assert.notNull(permissions, "未查询到此权限");

        //判断状态是否一致
        if (!permissions.getStatus().equals(status)) {
            permissions.setStatus(status);
            permissionsMapper.updateById(permissions);
        }
    }

    /**
     * 新增/编辑权限
     *
     * @param paramBO
     */
    @Transactional
    public void save(@Valid PermissionParamBO paramBO) {
        //判断编辑还是新增
        Long permissionId;
        Permissions permissions = permissionsMapper.getByCode(paramBO.getCode(), paramBO.getOwnerType());
        if (Objects.isNull(paramBO.getId())) {
            Assert.isNull(permissions, "此权限编码已存在");
            permissions = BeanUtils.map(paramBO, Permissions.class);
            permissions.setStatus(StatusEnum.NORMAL);

            permissionsMapper.insert(permissions);
            permissionId = permissions.getId();
        } else {
            Assert.isTrue(!(Objects.nonNull(permissions) && !permissions.getId().equals(paramBO.getId())), "此权限编码已存在");
            if (Objects.isNull(permissions)) {
                permissions = permissionsMapper.get(paramBO.getId());
            }
            StatusEnum statusEnum = permissions.getStatus();
            permissions = BeanUtils.map(paramBO, Permissions.class);
            permissions.setStatus(statusEnum);

            permissionsMapper.updateById(permissions);

            //清空关联数据
            usersPermissionsRefMapper.deleteResource(paramBO.getId());
            permissionId = paramBO.getId();
        }

        //批量更新关联资源
        if (!CollectionUtils.isEmpty(paramBO.getResources())) {
            //TODO 需求验证资源code是否有效
            List<UsersPermissionsRef> refList = paramBO.getResources().stream()
                    .map(x -> new UsersPermissionsRef().setPermissionId(permissionId).setResourceCode(x))
                    .collect(Collectors.toList());

            usersPermissionsRefMapper.batchInsert(refList);
        }
    }

    /**
     * 查询权限详情
     *
     * @param id
     * @return
     */
    public PermissionResultBO detail(long id) {
        Permissions permissions = permissionsMapper.get(id);
        Assert.notNull(permissions, "没有查询到此权限信息");
        PermissionResultBO resultBO = BeanUtils.map(permissions, PermissionResultBO.class);
        Set<String> resourceCodes = usersPermissionsRefMapper.findResourcesByPermissionId(Lists.newArrayList(permissions.getId()));
        if (!CollectionUtils.isEmpty(resourceCodes)) {
            List<Resources> resourcesList = resourcesMapper.findByCodes(resourceCodes);
            if (!CollectionUtils.isEmpty(resourcesList)) {
                List<ResourceResultBO> resultBOList = BeanUtils.mapList(resourcesList, ResourceResultBO.class);
                resultBO.setResources(resultBOList);
            }
        }
        return resultBO;
    }
}
